cmpl workaround for mmio regions
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 11 Jul 2005 09:00:12 +0000 (09:00 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 11 Jul 2005 09:00:12 +0000 (09:00 +0000)
Although we don't normally expect a guest to use cmpl against a MMIO region,
this may happen due to bugs. This workaround is needed for 64 bit linux-2.6.

Signed-off-by: Chengyuan Li <chengyuan.li@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
xen/arch/x86/vmx_platform.c

index f8ca5449581396e98066b1439979a83d686a0d65..04672e3b14cc3fd538d281579049bf065b946d97 100644 (file)
@@ -264,7 +264,7 @@ static inline unsigned long get_immediate(int op16, const unsigned char *inst, i
 
     switch(mod) {
         case 0:
-            if (rm == 5) {
+            if (rm == 5 || rm == 4) {
                 if (op16)
                     inst = inst + 2; //disp16, skip 2 bytes
                 else
@@ -361,6 +361,11 @@ static int vmx_decode(const unsigned char *inst, struct instruction *thread_inst
     }
 
     switch(*inst) {
+        case 0x81:
+            /* This is only a workaround for cmpl instruction*/
+            strcpy((char *)thread_inst->i_name, "cmp");
+            return DECODE_success;
+
         case 0x88:
             /* mov r8 to m8 */
             thread_inst->op_size = BYTE;
@@ -633,7 +638,6 @@ void handle_mmio(unsigned long va, unsigned long gpa)
 
     __vmread(GUEST_RIP, &eip);
     __vmread(INSTRUCTION_LEN, &inst_len);
-
     __vmread(GUEST_RFLAGS, &eflags);
     vm86 = eflags & X86_EFLAGS_VM;
 
@@ -735,6 +739,12 @@ void handle_mmio(unsigned long va, unsigned long gpa)
             inst_decoder_regs->eax, IOREQ_WRITE, 0);
         return;
     }
+    /* Workaround for cmp instruction */
+    if (!strncmp((char *)mmio_inst.i_name, "cmp", 3)) {
+        inst_decoder_regs->eflags &= ~X86_EFLAGS_ZF;
+        __vmwrite(GUEST_RFLAGS, inst_decoder_regs->eflags);
+        return;
+    }
 
     domain_crash_synchronous();
 }